/**
 * 
 */
package modul.imageSetCreator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import modul.AModul;
import modulIOContainer.DefaultImageContainer;

/**
 * @author Tony
 * 
 */
public class SunTrainingsSetCreator extends AModul {

	private boolean createNewSet = true;
	private boolean useTrainingsSet = true;
	private String imageSetSafeDirecory = null;
	private int nrOfImagesPerCategory = 10;
	private String imageRootDirectory = null;
	private String FileForCategoryMapping = null;

	/*
	 * (non-Javadoc)
	 * 
	 * @see modul.AModul#getOutputClass()
	 */
	@Override
	public Class<? extends DefaultImageContainer> getOutputClass() {

		return DefaultImageContainer.class;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see modul.AModul#getInputClass()
	 */
	@Override
	public Class<? extends DefaultImageContainer> getInputClass() {

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see modul.AModul#initialize(java.util.Properties)
	 */
	@Override
	public void initialize() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see modul.AModul#process()
	 */
	@Override
	public void process() {
		// load directories with category
		List<List<String>> categoryAndDirectory = this
				.loadDirectoriesPerCategory(this.FileForCategoryMapping);

		// load images
		List<List<String>> categoryWithImageURL = this
				.loadImageURLsFromDirectories(categoryAndDirectory);

		// reorder images
		this.reorderImagesPerCategory(categoryWithImageURL);

		// select x images per category, create container and add to output
		this.output = new ArrayList<DefaultImageContainer>();
		for (int i = 0; i < categoryWithImageURL.size(); i++) {
			if (categoryWithImageURL.get(i) != null) {
				List<String> files = categoryWithImageURL.get(i);

				for (int j = 0; j < files.size()
						&& j < this.nrOfImagesPerCategory; j++) {
					output.add(new DefaultImageContainer(files.get(j), i));
				}
			}
		}
		System.out.println("number of images loaded: "+this.output.size());
	}

	/**
	 * load the directories for each category
	 * 
	 * @param file
	 * @return
	 */
	private List<List<String>> loadDirectoriesPerCategory(String file) {
		ArrayList<List<String>> categories = new ArrayList<List<String>>();

		BufferedReader bf;
		try {
			bf = new BufferedReader(new FileReader(file));

			String line = bf.readLine();

			// reads all lines and save the maximum category number
			while (line != null) {
				if (!(line.compareTo("") == 0 || line.startsWith("#"))) {

					String[] buf = line.split(" ");

					if (buf.length > 1) {
						int categoryNr = Integer.parseInt(buf[0]);

						while(categories.size() - 1 < categoryNr){
							categories.add(new ArrayList<String>());
						}
							
//						if (categories.get(categoryNr) == null)
//							categories.set(categoryNr, new ArrayList<String>());
						// adds new directory
						categories.get(Integer.parseInt(buf[0])).add(buf[1]);
					}
				}

				line = bf.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}

		return categories;
	}

	private List<List<String>> loadImageURLsFromDirectories(
			List<List<String>> categoryAndDirectory) {
		List<List<String>> categoryAndFiles = new ArrayList<List<String>>();

		for (int i = 0; i < categoryAndDirectory.size(); i++) {

			if (categoryAndDirectory.get(i) != null)
				for (String dir : categoryAndDirectory.get(i)) {

					// get jpgs
					File f = new File(this.imageRootDirectory+dir);
					File[] files = f.listFiles(new FilenameFilter() {
						public boolean accept(File dir, String name) {
							return name.toLowerCase().endsWith(".jpg");
						}
					});
//					System.out.println(this.imageRootDirectory+dir);
					// add image files
					while(categoryAndFiles.size() - 1 < i){
						categoryAndFiles.add(new ArrayList<String>());
					}

					if( files!=null){						
						for(File file:files){
							categoryAndFiles.get(i).add(file.getAbsolutePath());							
						}
					}
					
				}
		}

		return categoryAndFiles;
	}

	private void reorderImagesPerCategory(
			List<List<String>> categoryWithImageURL) {
		for (int i = 0; i < categoryWithImageURL.size(); i++) {

			if (categoryWithImageURL.get(i) != null) {
				Collections.shuffle(categoryWithImageURL.get(i));
			}

		}
	}

	public boolean isCreateNewSet() {
		return createNewSet;
	}

	public void setCreateNewSet(boolean createNewSet) {
		this.createNewSet = createNewSet;
	}

	public boolean isUseTrainingsSet() {
		return useTrainingsSet;
	}

	public void setUseTrainingsSet(boolean useTrainingsSet) {
		this.useTrainingsSet = useTrainingsSet;
	}

	public String getImageSetSafeDirecory() {
		return imageSetSafeDirecory;
	}

	public void setImageSetSafeDirecory(String imageSetSafeDirecory) {
		this.imageSetSafeDirecory = imageSetSafeDirecory;
	}

	public int getNrOfImagesPerCategory() {
		return nrOfImagesPerCategory;
	}

	public void setNrOfImagesPerCategory(int nrOfImagesPerCategory) {
		this.nrOfImagesPerCategory = nrOfImagesPerCategory;
	}

	public String getImageRootDirectory() {
		return imageRootDirectory;
	}

	public void setImageRootDirectory(String imageRootDirectory) {
		this.imageRootDirectory = imageRootDirectory;
	}

	public String getFileForCategoryMapping() {
		return FileForCategoryMapping;
	}

	public void setFileForCategoryMapping(String fileForCategoryMapping) {
		FileForCategoryMapping = fileForCategoryMapping;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
